import itertools
import math
import random as disturb
from typing import List, Any, Union, Tuple

import numpy as np
from numpy import ndarray


def for_each(arr, function) -> List[Any]:
    result = []
    for item in arr:
        result.append(function(item))
    return result


def disturbance_floating(arr, magnification, reduction, increment=False) -> List[Union[float, Any]]:
    result = []
    if increment is True:
        diff_result = []
        diff_arr = np.diff(arr)
        for item in diff_arr:
            diff_result.append(item * disturb.uniform(reduction, magnification))
        diff_result.insert(0, arr[0] * disturb.uniform(reduction, magnification))
        result = list(itertools.accumulate(diff_result))
    else:
        for item in arr:
            result.append(item * disturb.uniform(reduction, magnification))
    return result


def split_array(arr, fold) -> Tuple[Any, Any]:
    result = np.split(arr, [math.ceil(len(arr) * fold)])
    return result[0], result[1]


def sum_sqrare_array(data) -> float:
    val = 0
    for item in data:
        val += item * item
    return val
